#include "strategies/ma_cross_strategy.h"
#include <spdlog/spdlog.h>
#include <algorithm>
#include <cmath>

namespace hft {

MACrossStrategy::MACrossStrategy() {
    // 初始化均线数�?
    fast_ma_.resize(fast_period_);
    slow_ma_.resize(slow_period_);
}

bool MACrossStrategy::init(const YAML::Node& config) {
    try {
        const auto& strategy_config = config["trading"]["strategy"];
        
        // 读取策略参数
        fast_period_ = strategy_config["fast_period"].as<int>();
        slow_period_ = strategy_config["slow_period"].as<int>();
        volume_ = strategy_config["volume"].as<double>();
        stop_loss_ = strategy_config["stop_loss"].as<double>();
        take_profit_ = strategy_config["take_profit"].as<double>();

        // 调整均线数据大小
        fast_ma_.resize(fast_period_);
        slow_ma_.resize(slow_period_);

        spdlog::info("MA Cross strategy initialized with parameters:");
        spdlog::info("Fast period: {}", fast_period_);
        spdlog::info("Slow period: {}", slow_period_);
        spdlog::info("Volume: {}", volume_);
        spdlog::info("Stop loss: {}", stop_loss_);
        spdlog::info("Take profit: {}", take_profit_);

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize MA Cross strategy: {}", e.what());
        return false;
    }
}

void MACrossStrategy::onMarketData(const MarketDataMessage& data) {
    // 更新价格数据
    prices_.push_back(data.last_price);
    if (prices_.size() > slow_period_) {
        prices_.pop_front();
    }

    // 检查止损止盈
    checkStopLossTakeProfit(data);

    // 计算均线
    if (prices_.size() >= slow_period_) {
        double fast_ma = calculateMA(prices_, fast_period_);
        double slow_ma = calculateMA(prices_, slow_period_);

        fast_ma_.push_back(fast_ma);
        slow_ma_.push_back(slow_ma);

        if (fast_ma_.size() > fast_period_) {
            fast_ma_.erase(fast_ma_.begin());
        }
        if (slow_ma_.size() > slow_period_) {
            slow_ma_.erase(slow_ma_.begin());
        }

        // 生成交易信号
        int signal = generateSignal();
        if (signal != 0 && signal != last_signal_) {
            spdlog::info("New signal generated: {}", signal);
            
            // 检查是否可以开仓或平仓
            if (signal > 0 && canOpenPosition(data.symbol)) {
                // 开多仓
                Order order;
                order.symbol = data.symbol;
                order.direction = OrderDirection::BUY;
                order.offset = OrderOffset::OPEN;
                order.price = data.ask_price;
                order.volume = volume_;
                placeOrder(order);
                spdlog::info("Placed long order at {}", order.price);
            } else if (signal < 0 && canOpenPosition(data.symbol)) {
                // 开空仓
                Order order;
                order.symbol = data.symbol;
                order.direction = OrderDirection::SELL;
                order.offset = OrderOffset::OPEN;
                order.price = data.bid_price;
                order.volume = volume_;
                placeOrder(order);
                spdlog::info("Placed short order at {}", order.price);
            } else if (signal < 0 && canClosePosition(data.symbol)) {
                // 平多仓
                Order order;
                order.symbol = data.symbol;
                order.direction = OrderDirection::SELL;
                order.offset = OrderOffset::CLOSE;
                order.price = data.bid_price;
                order.volume = volume_;
                placeOrder(order);
                spdlog::info("Closed long position at {}", order.price);
            } else if (signal > 0 && canClosePosition(data.symbol)) {
                // 平空仓
                Order order;
                order.symbol = data.symbol;
                order.direction = OrderDirection::BUY;
                order.offset = OrderOffset::CLOSE;
                order.price = data.ask_price;
                order.volume = volume_;
                placeOrder(order);
                spdlog::info("Closed short position at {}", order.price);
            }
        }
        last_signal_ = signal;
    }
}

void MACrossStrategy::checkStopLossTakeProfit(const MarketDataMessage& data) {
    auto it = positions_.find(data.symbol);
    if (it == positions_.end()) {
        return;
    }

    const Position& position = it->second;
    double current_price = data.last_price;
    double pnl = 0.0;

    // 检查多头仓位
    if (position.long_volume > 0) {
        pnl = (current_price - position.long_price) / position.long_price;
        if (pnl <= -stop_loss_ || pnl >= take_profit_) {
            // 平多仓
            Order order;
            order.symbol = data.symbol;
            order.direction = OrderDirection::SELL;
            order.offset = OrderOffset::CLOSE;
            order.price = data.bid_price;
            order.volume = position.long_volume;
            placeOrder(order);
            spdlog::warn("Closing long position due to {}: price={} pnl={:.2f}%",
                pnl <= -stop_loss_ ? "stop loss" : "take profit", 
                current_price, pnl * 100);
        }
    }

    // 检查空头仓位
    if (position.short_volume > 0) {
        pnl = (position.short_price - current_price) / position.short_price;
        if (pnl <= -stop_loss_ || pnl >= take_profit_) {
            // 平空仓
            Order order;
            order.symbol = data.symbol;
            order.direction = OrderDirection::BUY;
            order.offset = OrderOffset::CLOSE;
            order.price = data.ask_price;
            order.volume = position.short_volume;
            placeOrder(order);
            spdlog::warn("Closing short position due to {}: price={} pnl={:.2f}%",
                pnl <= -stop_loss_ ? "stop loss" : "take profit",
                current_price, pnl * 100);
        }
    }
}

void MACrossStrategy::onTrade(const Trade& trade) {
    // 更新持仓信息
    auto it = positions_.find(trade.symbol);
    if (it != positions_.end()) {
        Position& position = it->second;
        if (trade.direction == OrderDirection::BUY) {
            if (trade.offset == OrderOffset::OPEN) {
                position.long_volume += trade.volume;
            } else {
                position.short_volume -= trade.volume;
            }
        } else {
            if (trade.offset == OrderOffset::OPEN) {
                position.short_volume += trade.volume;
            } else {
                position.long_volume -= trade.volume;
            }
        }
    }
}

void MACrossStrategy::onPosition(const Position& position) {
    positions_[position.symbol] = position;
}

void MACrossStrategy::onAccount(const Account& account) {
    account_ = account;
}

bool MACrossStrategy::placeOrder(const Order& order) {
    // 检查账户资金是否足�?
    double required_margin = order.price * order.volume * 0.1; // 假设保证金比例为10%
    if (account_.available < required_margin) {
        spdlog::warn("Insufficient margin for order: {}", order.order_id);
        return false;
    }

    // 记录订单
    orders_[order.order_id] = order;
    return true;
}

bool MACrossStrategy::cancelOrder(const std::string& order_id) {
    auto it = orders_.find(order_id);
    if (it != orders_.end()) {
        orders_.erase(it);
        return true;
    }
    return false;
}

YAML::Node MACrossStrategy::getParams() const {
    YAML::Node params;
    params["fast_period"] = fast_period_;
    params["slow_period"] = slow_period_;
    params["volume"] = volume_;
    params["stop_loss"] = stop_loss_;
    params["take_profit"] = take_profit_;
    return params;
}

bool MACrossStrategy::setParams(const YAML::Node& params) {
    try {
        if (params["fast_period"]) {
            fast_period_ = params["fast_period"].as<int>();
            fast_ma_.resize(fast_period_);
        }
        if (params["slow_period"]) {
            slow_period_ = params["slow_period"].as<int>();
            slow_ma_.resize(slow_period_);
        }
        if (params["volume"]) {
            volume_ = params["volume"].as<double>();
        }
        if (params["stop_loss"]) {
            stop_loss_ = params["stop_loss"].as<double>();
        }
        if (params["take_profit"]) {
            take_profit_ = params["take_profit"].as<double>();
        }
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to set parameters: {}", e.what());
        return false;
    }
}

double MACrossStrategy::calculateMA(const std::deque<double>& prices, int period) {
    if (prices.size() < period) {
        spdlog::debug("Not enough prices ({}) to calculate {}-period MA", prices.size(), period);
        return 0.0;
    }
    
    // 使用更高效的累加方法
    auto begin = prices.end() - period;
    auto end = prices.end();
    double sum = std::accumulate(begin, end, 0.0);
    
    double ma = sum / period;
    spdlog::trace("Calculated {}-period MA: {}", period, ma);
    return ma;
}

int MACrossStrategy::generateSignal() {
    if (fast_ma_.size() < 2 || slow_ma_.size() < 2) {
        return 0;
    }

    // 计算当前和前一个周期的均线差�?
    double current_diff = fast_ma_.back() - slow_ma_.back();
    double prev_diff = fast_ma_[fast_ma_.size() - 2] - slow_ma_[slow_ma_.size() - 2];

    // 生成信号
    if (current_diff > 0 && prev_diff <= 0) {
        return 1;  // 金叉，做多信�?
    } else if (current_diff < 0 && prev_diff >= 0) {
        return -1; // 死叉，做空信�?
    }
    return 0;
}

bool MACrossStrategy::canOpenPosition(const std::string& symbol) {
    auto it = positions_.find(symbol);
    if (it == positions_.end()) {
        return true;
    }
    const Position& position = it->second;
    return position.long_volume == 0 && position.short_volume == 0;
}

bool MACrossStrategy::canClosePosition(const std::string& symbol) {
    auto it = positions_.find(symbol);
    if (it == positions_.end()) {
        return false;
    }
    const Position& position = it->second;
    return position.long_volume > 0 || position.short_volume > 0;
}

} // namespace hft 